const crypto = require('crypto');
const axios = require('axios');
const { promisify } = require('util');
const { logger } = require('../utils/logger');

/**
 * 支付服务类
 * 集成支付宝、微信支付、Apple Pay、Google Pay等支付方式
 */
class PaymentService {
  constructor() {
    // 支付宝配置
    this.alipayConfig = {
      appId: process.env.ALIPAY_APP_ID,
      privateKey: process.env.ALIPAY_PRIVATE_KEY,
      publicKey: process.env.ALIPAY_PUBLIC_KEY,
      gatewayUrl: process.env.ALIPAY_GATEWAY_URL || 'https://openapi.alipay.com/gateway.do',
      notifyUrl: process.env.ALIPAY_NOTIFY_URL,
      returnUrl: process.env.ALIPAY_RETURN_URL
    };

    // 微信支付配置
    this.wechatConfig = {
      appId: process.env.WECHAT_APP_ID,
      mchId: process.env.WECHAT_MCH_ID,
      apiKey: process.env.WECHAT_API_KEY,
      certPath: process.env.WECHAT_CERT_PATH,
      keyPath: process.env.WECHAT_KEY_PATH,
      notifyUrl: process.env.WECHAT_NOTIFY_URL
    };

    // Apple Pay配置
    this.applePayConfig = {
      merchantId: process.env.APPLE_PAY_MERCHANT_ID,
      merchantDomain: process.env.APPLE_PAY_MERCHANT_DOMAIN,
      certificatePath: process.env.APPLE_PAY_CERT_PATH
    };

    // Google Pay配置
    this.googlePayConfig = {
      merchantId: process.env.GOOGLE_PAY_MERCHANT_ID,
      merchantName: process.env.GOOGLE_PAY_MERCHANT_NAME || 'CU MR BULL'
    };
  }

  /**
   * 创建支付订单
   * @param {Object} paymentData - 支付数据
   * @param {string} paymentData.method - 支付方式 (alipay, wechat, apple_pay, google_pay, cash, card)
   * @param {number} paymentData.amount - 支付金额
   * @param {string} paymentData.orderId - 订单ID
   * @param {string} paymentData.orderNumber - 订单号
   * @param {string} paymentData.description - 订单描述
   * @param {Object} paymentData.userInfo - 用户信息
   * @returns {Object} 支付结果
   */
  async createPayment(paymentData) {
    const { method, amount, orderId, orderNumber, description, userInfo } = paymentData;

    try {
      switch (method) {
        case 'alipay':
          return await this.createAlipayOrder(paymentData);
        case 'wechat':
          return await this.createWechatOrder(paymentData);
        case 'apple_pay':
          return await this.createApplePayOrder(paymentData);
        case 'google_pay':
          return await this.createGooglePayOrder(paymentData);
        case 'cash':
          return await this.createCashPayment(paymentData);
        case 'card':
          return await this.createCardPayment(paymentData);
        default:
          throw new Error(`不支持的支付方式: ${method}`);
      }
    } catch (error) {
      logger.error('创建支付订单失败:', error);
      throw error;
    }
  }

  /**
   * 创建支付宝订单
   */
  async createAlipayOrder(paymentData) {
    const { amount, orderNumber, description } = paymentData;

    // 构建支付宝请求参数
    const params = {
      app_id: this.alipayConfig.appId,
      method: 'alipay.trade.app.pay',
      format: 'JSON',
      charset: 'utf-8',
      sign_type: 'RSA2',
      timestamp: new Date().toISOString().replace('T', ' ').substring(0, 19),
      version: '1.0',
      notify_url: this.alipayConfig.notifyUrl,
      biz_content: JSON.stringify({
        out_trade_no: orderNumber,
        total_amount: amount.toFixed(2),
        subject: description || '餐厅订单支付',
        product_code: 'QUICK_MSECURITY_PAY'
      })
    };

    // 生成签名
    const sign = this.generateAlipaySign(params);
    params.sign = sign;

    return {
      success: true,
      paymentMethod: 'alipay',
      paymentUrl: this.buildAlipayUrl(params),
      paymentParams: params,
      orderId: paymentData.orderId,
      orderNumber: orderNumber,
      amount: amount
    };
  }

  /**
   * 创建微信支付订单
   */
  async createWechatOrder(paymentData) {
    const { amount, orderNumber, description, userInfo } = paymentData;

    // 构建微信支付请求参数
    const params = {
      appid: this.wechatConfig.appId,
      mch_id: this.wechatConfig.mchId,
      nonce_str: this.generateNonceStr(),
      body: description || '餐厅订单支付',
      out_trade_no: orderNumber,
      total_fee: Math.round(amount * 100), // 微信支付金额单位为分
      spbill_create_ip: '127.0.0.1', // 实际应用中应获取真实IP
      notify_url: this.wechatConfig.notifyUrl,
      trade_type: 'APP'
    };

    // 生成签名
    const sign = this.generateWechatSign(params);
    params.sign = sign;

    try {
      // 调用微信统一下单接口
      const response = await this.callWechatAPI('https://api.mch.weixin.qq.com/pay/unifiedorder', params);
      
      if (response.return_code === 'SUCCESS' && response.result_code === 'SUCCESS') {
        // 构建APP调起支付的参数
        const appPayParams = {
          appid: this.wechatConfig.appId,
          partnerid: this.wechatConfig.mchId,
          prepayid: response.prepay_id,
          package: 'Sign=WXPay',
          noncestr: this.generateNonceStr(),
          timestamp: Math.floor(Date.now() / 1000).toString()
        };
        
        appPayParams.sign = this.generateWechatSign(appPayParams);

        return {
          success: true,
          paymentMethod: 'wechat',
          paymentParams: appPayParams,
          prepayId: response.prepay_id,
          orderId: paymentData.orderId,
          orderNumber: orderNumber,
          amount: amount
        };
      } else {
        throw new Error(`微信支付失败: ${response.err_code_des || response.return_msg}`);
      }
    } catch (error) {
      logger.error('微信支付创建失败:', error);
      throw error;
    }
  }

  /**
   * 创建Apple Pay订单
   */
  async createApplePayOrder(paymentData) {
    const { amount, orderNumber, description } = paymentData;

    // Apple Pay 主要在前端处理，后端提供配置信息
    return {
      success: true,
      paymentMethod: 'apple_pay',
      merchantId: this.applePayConfig.merchantId,
      merchantDomain: this.applePayConfig.merchantDomain,
      paymentRequest: {
        countryCode: 'SG', // 新加坡
        currencyCode: 'SGD',
        total: {
          label: description || '餐厅订单支付',
          amount: amount.toFixed(2)
        },
        merchantCapabilities: ['supports3DS'],
        supportedNetworks: ['visa', 'masterCard', 'amex']
      },
      orderId: paymentData.orderId,
      orderNumber: orderNumber,
      amount: amount
    };
  }

  /**
   * 创建Google Pay订单
   */
  async createGooglePayOrder(paymentData) {
    const { amount, orderNumber, description } = paymentData;

    // Google Pay 主要在前端处理，后端提供配置信息
    return {
      success: true,
      paymentMethod: 'google_pay',
      merchantId: this.googlePayConfig.merchantId,
      merchantName: this.googlePayConfig.merchantName,
      paymentRequest: {
        apiVersion: 2,
        apiVersionMinor: 0,
        allowedPaymentMethods: [{
          type: 'CARD',
          parameters: {
            allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
            allowedCardNetworks: ['AMEX', 'DISCOVER', 'JCB', 'MASTERCARD', 'VISA']
          },
          tokenizationSpecification: {
            type: 'PAYMENT_GATEWAY',
            parameters: {
              gateway: 'example',
              gatewayMerchantId: this.googlePayConfig.merchantId
            }
          }
        }],
        transactionInfo: {
          totalPriceStatus: 'FINAL',
          totalPrice: amount.toFixed(2),
          currencyCode: 'SGD',
          countryCode: 'SG'
        },
        merchantInfo: {
          merchantName: this.googlePayConfig.merchantName
        }
      },
      orderId: paymentData.orderId,
      orderNumber: orderNumber,
      amount: amount
    };
  }

  /**
   * 创建现金支付
   */
  async createCashPayment(paymentData) {
    const { amount, orderNumber } = paymentData;

    return {
      success: true,
      paymentMethod: 'cash',
      status: 'pending', // 现金支付需要人工确认
      orderId: paymentData.orderId,
      orderNumber: orderNumber,
      amount: amount,
      message: '请在收银台完成现金支付'
    };
  }

  /**
   * 创建刷卡支付
   */
  async createCardPayment(paymentData) {
    const { amount, orderNumber } = paymentData;

    return {
      success: true,
      paymentMethod: 'card',
      status: 'pending', // 刷卡支付需要POS机确认
      orderId: paymentData.orderId,
      orderNumber: orderNumber,
      amount: amount,
      message: '请在POS机上完成刷卡支付'
    };
  }

  /**
   * 验证支付回调
   */
  async verifyPaymentCallback(method, callbackData) {
    try {
      switch (method) {
        case 'alipay':
          return await this.verifyAlipayCallback(callbackData);
        case 'wechat':
          return await this.verifyWechatCallback(callbackData);
        default:
          throw new Error(`不支持的支付方式回调验证: ${method}`);
      }
    } catch (error) {
      logger.error('支付回调验证失败:', error);
      throw error;
    }
  }

  /**
   * 验证支付宝回调
   */
  async verifyAlipayCallback(callbackData) {
    // 验证支付宝签名
    const sign = callbackData.sign;
    delete callbackData.sign;
    delete callbackData.sign_type;

    const expectedSign = this.generateAlipaySign(callbackData);
    
    if (sign !== expectedSign) {
      throw new Error('支付宝回调签名验证失败');
    }

    return {
      success: true,
      orderNumber: callbackData.out_trade_no,
      transactionId: callbackData.trade_no,
      amount: parseFloat(callbackData.total_amount),
      status: callbackData.trade_status === 'TRADE_SUCCESS' ? 'completed' : 'failed'
    };
  }

  /**
   * 验证微信支付回调
   */
  async verifyWechatCallback(callbackData) {
    // 验证微信支付签名
    const sign = callbackData.sign;
    delete callbackData.sign;

    const expectedSign = this.generateWechatSign(callbackData);
    
    if (sign !== expectedSign) {
      throw new Error('微信支付回调签名验证失败');
    }

    return {
      success: true,
      orderNumber: callbackData.out_trade_no,
      transactionId: callbackData.transaction_id,
      amount: parseInt(callbackData.total_fee) / 100, // 微信支付金额单位为分
      status: callbackData.result_code === 'SUCCESS' ? 'completed' : 'failed'
    };
  }

  /**
   * 生成支付宝签名
   */
  generateAlipaySign(params) {
    // 排序参数
    const sortedParams = Object.keys(params)
      .filter(key => params[key] !== '' && params[key] !== null && params[key] !== undefined)
      .sort()
      .map(key => `${key}=${params[key]}`)
      .join('&');

    // 使用RSA2签名
    const sign = crypto.createSign('RSA-SHA256');
    sign.update(sortedParams, 'utf8');
    return sign.sign(this.alipayConfig.privateKey, 'base64');
  }

  /**
   * 生成微信支付签名
   */
  generateWechatSign(params) {
    // 排序参数
    const sortedParams = Object.keys(params)
      .filter(key => params[key] !== '' && params[key] !== null && params[key] !== undefined)
      .sort()
      .map(key => `${key}=${params[key]}`)
      .join('&');

    // 添加API密钥
    const stringSignTemp = `${sortedParams}&key=${this.wechatConfig.apiKey}`;
    
    // MD5签名
    return crypto.createHash('md5').update(stringSignTemp, 'utf8').digest('hex').toUpperCase();
  }

  /**
   * 构建支付宝支付URL
   */
  buildAlipayUrl(params) {
    const queryString = Object.keys(params)
      .map(key => `${key}=${encodeURIComponent(params[key])}`)
      .join('&');
    
    return `${this.alipayConfig.gatewayUrl}?${queryString}`;
  }

  /**
   * 生成随机字符串
   */
  generateNonceStr(length = 32) {
    const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    let result = '';
    for (let i = 0; i < length; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
  }

  /**
   * 调用微信API
   */
  async callWechatAPI(url, params) {
    const xml = this.buildXML(params);
    
    try {
      const response = await axios.post(url, xml, {
        headers: {
          'Content-Type': 'application/xml'
        }
      });
      
      return this.parseXML(response.data);
    } catch (error) {
      logger.error('微信API调用失败:', error);
      throw error;
    }
  }

  /**
   * 构建XML
   */
  buildXML(params) {
    let xml = '<xml>';
    Object.keys(params).forEach(key => {
      xml += `<${key}><![CDATA[${params[key]}]]></${key}>`;
    });
    xml += '</xml>';
    return xml;
  }

  /**
   * 解析XML
   */
  parseXML(xml) {
    const result = {};
    const regex = /<(\w+)><!\[CDATA\[([^\]]+)\]\]><\/\1>/g;
    let match;
    
    while ((match = regex.exec(xml)) !== null) {
      result[match[1]] = match[2];
    }
    
    return result;
  }

  /**
   * 查询支付状态
   */
  async queryPaymentStatus(method, orderNumber) {
    try {
      switch (method) {
        case 'alipay':
          return await this.queryAlipayStatus(orderNumber);
        case 'wechat':
          return await this.queryWechatStatus(orderNumber);
        default:
          throw new Error(`不支持的支付状态查询: ${method}`);
      }
    } catch (error) {
      logger.error('查询支付状态失败:', error);
      throw error;
    }
  }

  /**
   * 查询支付宝支付状态
   */
  async queryAlipayStatus(orderNumber) {
    // 实现支付宝订单查询逻辑
    // 这里返回模拟数据
    return {
      success: true,
      orderNumber: orderNumber,
      status: 'pending',
      message: '支付宝订单查询功能开发中'
    };
  }

  /**
   * 查询微信支付状态
   */
  async queryWechatStatus(orderNumber) {
    // 实现微信支付订单查询逻辑
    // 这里返回模拟数据
    return {
      success: true,
      orderNumber: orderNumber,
      status: 'pending',
      message: '微信支付订单查询功能开发中'
    };
  }
}

module.exports = PaymentService;